package com.intel.surface;

import com.google.gson.Gson;
import com.intel.bluetooth.ConnectService;
import com.intel.bluetooth.DiscoveryService;

import javax.bluetooth.RemoteDevice;
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.Set;

public class DeviceListFrame extends JFrame {

    private static final long serialVersionUID = 1L;
    private JMenuBar menuBar;
    private JMenu menu;
    private JMenuItem menuItem;
    private JPanel connectedPn;
    private JPanel unconnectPn;
    private JPanel bottom;
    private JLabel discoverDeviceLb;
    private JLabel discoverDeviceBt;
    private Set<String> connectedDevice;

    public DeviceListFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setBackground(new Color(255, 255, 255));
        setBounds(100, 100, 380, 550);
        setResizable(false);
        setTitle("附近的设备");
        getContentPane().setLayout(new BorderLayout(0, 0));

        connectedDevice = new HashSet<>();
        bottom = new JPanel();
        bottom.setBackground(new Color(255, 255, 255));
        bottom.setPreferredSize(new Dimension(0, 40));
        getContentPane().add(bottom, BorderLayout.SOUTH);

        discoverDeviceLb = new JLabel(" 正在搜索设备...");
        discoverDeviceLb.setFont(new Font("黑体", Font.BOLD, 14));
        discoverDeviceLb.setIcon(new ImageIcon("img/wait.gif"));

        discoverDeviceBt = new JLabel("重新搜索");
        discoverDeviceBt.setHorizontalAlignment(SwingConstants.CENTER);
        discoverDeviceBt.setHorizontalTextPosition(SwingConstants.CENTER);
        discoverDeviceBt.setPreferredSize(new Dimension(84, 30));
        discoverDeviceBt.setBorder(new LineBorder(new Color(0, 191, 255)));
        discoverDeviceBt.setForeground(new Color(0, 191, 255));
        discoverDeviceBt.setFont(new Font("黑体", Font.BOLD, 15));
        discoverDeviceBt.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

        bottom.add(discoverDeviceLb);

        JPanel listPn = new JPanel();
        listPn.setBackground(new Color(255, 255, 255));
        listPn.setLayout(new VFlowLayout());
        JScrollPane scrollPane = new JScrollPane(listPn);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        JLabel lb1 = new JLabel("已连接设备");
        lb1.setForeground(Color.GRAY);
        lb1.setFont(new Font("黑体", Font.BOLD, 15));
        connectedPn = new JPanel(new VFlowLayout());
        connectedPn.setBackground(new Color(255, 255, 255));
        JLabel lb2 = new JLabel("可连接设备");
        lb2.setForeground(Color.GRAY);
        lb2.setFont(new Font("黑体", Font.BOLD, 15));
        unconnectPn = new JPanel(new VFlowLayout());
        unconnectPn.setBackground(new Color(255, 255, 255));

        listPn.add(lb1);
        listPn.add(connectedPn);
        listPn.add(lb2);
        listPn.add(unconnectPn);

        menuBar = new JMenuBar();
        getContentPane().add(menuBar, BorderLayout.NORTH);

        menu = new JMenu("设置");
        menuBar.add(menu);

        menuItem = new JMenuItem("服务器地址");
        menu.add(menuItem);
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                SettingConfig settingConfig = SettingConfig.getInstance();
                IpSetDlg ipSetDlg = new IpSetDlg(settingConfig.getServerAddress() + ":" + settingConfig.getServerPort());
                ipSetDlg.setVisible(true);
            }
        });

        addListeners();
        findDevices();
    }

    private void addListeners() {
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                Gson gson = new Gson();

                try {
                    FileOutputStream out = new FileOutputStream("config/config.json");
                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
                    String s = gson.toJson(SettingConfig.getInstance());

                    s = s.replaceAll("[{]", "{\r\n");
                    s = s.replaceAll("[}]", "\r\n}");
                    s = s.replaceAll(",", ",\r\n");

                    writer.write(s);
                    writer.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });

        discoverDeviceBt.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                findDevices();
            }

        });
    }

    // 查找设备
    public void findDevices() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                unconnectPn.removeAll();
                unconnectPn.updateUI();

                bottom.removeAll();
                bottom.add(discoverDeviceLb);
                bottom.updateUI();
            }
        });
        ThreadUtil.execute(new Runnable() {
            @Override
            public void run() {
                DiscoveryService discoveryService = new DiscoveryService();
                Set<RemoteDevice> devicesDiscovered = discoveryService.findDevices();
                for (RemoteDevice remoteDevice : devicesDiscovered) {
                    if (connectedDevice.contains(remoteDevice.getBluetoothAddress()))
                        continue;
                    UnconnectDevicePn unconnectDevicePn = new UnconnectDevicePn(DeviceListFrame.this, remoteDevice);
                    unconnectPn.add(unconnectDevicePn);
                }

                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        unconnectPn.updateUI();
                        discoverDeviceCompleted();
                    }
                });
            }
        });

    }

    // 查找设备完成
    private void discoverDeviceCompleted() {
        bottom.removeAll();
        bottom.add(discoverDeviceBt);
        bottom.updateUI();
    }

    public void connectSuccess(UnconnectDevicePn unconnectDevicePn, ConnectService connectService) {
        if (connectedDevice.contains(unconnectDevicePn.getRemoteDevice().getBluetoothAddress()))
            return;

        ConnectedDevicePn connectedDevicePn = new ConnectedDevicePn(connectService);
        connectedDevice.add(unconnectDevicePn.getRemoteDevice().getBluetoothAddress());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                unconnectPn.remove(unconnectDevicePn);
                unconnectPn.updateUI();

                connectedPn.add(connectedDevicePn);
                connectedPn.updateUI();
            }
        });
    }

    public void removeLostConnection(ConnectedDevicePn connectedDevicePn) {
        if (connectedDevicePn != null) {
            connectedDevice.remove(connectedDevicePn.getConnectService().getDeviceConnectService().getRemoteDevice().getBluetoothAddress());
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    connectedPn.remove(connectedDevicePn);
                    connectedPn.updateUI();
                }
            });
        }
    }
}
